package com.lizard.schedule.manager.observer;

import com.lizard.schedule.persistence.db.bean.Schedule;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 通用的观察者通知管理类
 * 注意!!!! 注册观察者的地方一定要在相应的地方移除该条观察者，否则会内存泄露
 */
public class ObserverManager {

    private static ObserverManager instance;

    private ObserverManager(){}

    private List<ObserverIfaces.UpdateScheduleToUi> mUpdateScheduleToUis = new ArrayList<ObserverIfaces.UpdateScheduleToUi>();

    private List<ObserverIfaces.ReloadUnfinishedHistoryScheduleCount> mReloadUnfinishedHistoryScheduleCounts = new ArrayList<ObserverIfaces.ReloadUnfinishedHistoryScheduleCount>();

    private List<ObserverIfaces.SyncListener> mSyncListeners = new ArrayList<ObserverIfaces.SyncListener>();

    private List<ObserverIfaces.Logout> mLogouts = new ArrayList<ObserverIfaces.Logout>();

    public static ObserverManager getInstance(){
        if(instance == null){
            synchronized (ObserverManager.class){
                if(instance == null){
                    instance = new ObserverManager();
                }
            }
        }
        return instance;
    }

    /**
     * 注册观察者 同步监听接口
     *
     * @param listener
     */
    public void registerSyncListener(ObserverIfaces.SyncListener listener){
        mSyncListeners.add(listener);
    }

    /**
     * 移除观察者 同步监听接口
     * @param listener
     */
    public void unregisterSyncListener(ObserverIfaces.SyncListener listener){
        mSyncListeners.remove(listener);
    }

    /**
     * 通知观察者 同步监听接口 网络错误
     */
    public void notifySyncListenersNetWorkError(){
        for(ObserverIfaces.SyncListener listener: mSyncListeners){
            listener.netWorkError();
        }
    }

    /**
     * 通知观察者 同步监听接口 已是最新数据，无需同步(client无更新提交，server也无新数据)
     */
    public void notifySyncListenerNoSync(){
        for(ObserverIfaces.SyncListener listener: mSyncListeners){
            listener.noSync();
        }
    }

    /**
     * 通知观察者 同步监听接口 有新数据从server同步下来(已更新到本地db)
     */
    public void notifySyncListenerNewData(List<Schedule> addList, List<Schedule> updateList, List<Schedule> deleteList){
        for(ObserverIfaces.SyncListener listener: mSyncListeners){
            listener.newData(addList, updateList, deleteList);
        }
    }

    /**
     * 通知观察者 同步监听接口 同步成功,server的新数据同步到本地,本地的修改也提交到server（已更新到本地db）
     */
    public void notifySyncListenerSyncSuccess(List<Integer> submitedLocalIds, Map<Integer, Long> addedServerIds){
        for(ObserverIfaces.SyncListener listener: mSyncListeners){
            listener.syncSuccess(submitedLocalIds, addedServerIds);
        }
    }

    /**
     * 注册观察者 通知界面更新计划
     *
     * @param observer
     */
    public void registerUpdateScheduleToUi(ObserverIfaces.UpdateScheduleToUi observer){
        mUpdateScheduleToUis.add(observer);
    }

    /**
     * 移除观察者 通知界面更新计划
     *
     * @param observer
     */
    public void unregisterUpdateScheduleToUi(ObserverIfaces.UpdateScheduleToUi observer){
        mUpdateScheduleToUis.remove(observer);
    }

    /**
     * 通知观察者 通知界面更新计划
     * @param schedule
     */
    public void notifyUpdateScheduleToUis(Schedule schedule){
        for(ObserverIfaces.UpdateScheduleToUi observer: mUpdateScheduleToUis){
            observer.update(schedule);
        }
    }

    /**
     * 注册观察者 通知界面重新加载未结束的历史计划数
     *
     * @param observer
     */
    public void registerReloadUnfinishedHistoryScheduleCount(ObserverIfaces.ReloadUnfinishedHistoryScheduleCount observer){
        mReloadUnfinishedHistoryScheduleCounts.add(observer);
    }

    /**
     * 移除观察者 通知界面重新加载未结束的历史计划数
     * @param observer
     */
    public void unregisterReloadUnfinishedHistoryScheduleCount(ObserverIfaces.ReloadUnfinishedHistoryScheduleCount observer){
        mReloadUnfinishedHistoryScheduleCounts.remove(observer);
    }

    /**
     * 通知观察者 通知界面重新加载未结束的历史计划数
     */
    public void notifyReloadUnfinishedHistoryScheduleCounts(){
        for(ObserverIfaces.ReloadUnfinishedHistoryScheduleCount observer: mReloadUnfinishedHistoryScheduleCounts){
            observer.reload();
        }
    }

    /**
     * 注册观察者 通知退出登录
     *
     * @param observer
     */
    public void registerLogout(ObserverIfaces.Logout observer){
        mLogouts.add(observer);
    }

    /**
     * 移除观察者 通知退出登录
     *
     * @param observer
     */
    public void unregisterLogout(ObserverIfaces.Logout observer){
        mLogouts.remove(observer);
    }

    /**
     * 通知观察者 通知退出登录
     */
    public void notifyLogouts(){
        for(ObserverIfaces.Logout observer: mLogouts){
            observer.logout();
        }
    }

}
